package cn.pegasus.teamwork.weixinpay.service.impl;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import cn.pegasus.teamwork.vo.WXOrderVO;
import cn.pegasus.teamwork.weixinpay.Constant;
import cn.pegasus.teamwork.weixinpay.model.PaySendData;
import cn.pegasus.teamwork.weixinpay.service.PayService;
import cn.pegasus.teamwork.weixinpay.util.HttpUtil;
import cn.pegasus.teamwork.weixinpay.util.PayUtils;

@Service("payService")
public class PayServiceImpl implements PayService {
	private static final Logger LOGGER = LoggerFactory.getLogger(PayServiceImpl.class);

	/**
	 * 微信支付统一下单
	 **/
	public Map<String, Object> unifiedOrder(WXOrderVO VO) {
		Map<String, Object> resultMap = null;
		SortedMap<String, Object> payMap = new TreeMap<String, Object>();
		// 统一下单返回的预支付id
		String prepayId = null;
		PaySendData paySendData = new PaySendData();
		// 构建微信支付请求参数集合
		paySendData.setAppId(Constant.APP_ID);
		paySendData.setMch_id(Constant.MCH_ID);
		paySendData.setNotify_url(VO.getNotityUrl());
		paySendData.setTrade_type(Constant.TRADE_TYPE_JSAPI);
		paySendData.setDevice_info(Constant.WEB);
		paySendData.setBody(VO.getBody());
		paySendData.setNonce_str(PayUtils.getRandomStr(32));
		paySendData.setOut_trade_no(VO.getOrderNo());
		paySendData.setTotal_fee(VO.getOrderBalance());
		paySendData.setSpbill_create_ip(Constant.CREATEIP);
		paySendData.setOpenId(VO.getOpenid());
		// 将参数拼成map,生产签名
		String sign = PayUtils.getSign(buildParamMap(paySendData));
		paySendData.setSign(sign);
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.Post(Constant.UNIFIED_ORDER_URL, reqXml, false);
			try {
				resultMap = PayUtils.parseXml(response.getEntity().getContent());
				// 关闭流
				EntityUtils.consume(response.getEntity());
			} finally {
				response.close();
			}
		} catch (Exception e) {
			LOGGER.error("微信支付统一下单异常");
		}
		String return_code = resultMap.get("return_code").toString();
		String result_code = resultMap.get("result_code").toString();
		if (Constant.RETURN_SUCCESS.equals(return_code) && Constant.RETURN_SUCCESS.equals(result_code)) {
			// return_code=通信标识
			// result_code=交易标识
			// 只有当returnCode与resultCode均返回“success”，才代表微信支付统一下单成功
			prepayId = resultMap.get("prepay_id").toString();

			if (!StringUtils.isEmpty(prepayId)) {
				payMap.put("appId", Constant.APP_ID);
				String timeStamp = PayUtils.getTimeStamp();// 当前时间戳
				String nonceStr = PayUtils.getRandomStr(20);// 不长于32位的随机字符串
				payMap.put("timeStamp", timeStamp);
				payMap.put("nonceStr", nonceStr);
				payMap.put("signType", "MD5");
				payMap.put("package", "prepay_id=" + prepayId);

				String paySign = PayUtils.getSign(payMap);
				payMap.put("package", prepayId);
				payMap.put("paySign", paySign);
				return payMap;
			}

		}
		return payMap;
	}
	
	/**
	 * 微信支付统一下单
	 **/
	public Map<String, Object> unifiedOrderForApp(WXOrderVO VO) {
		Map<String, Object> resultMap = null;
		SortedMap<String, Object> payMap = new TreeMap<String, Object>();
		// 统一下单返回的预支付id
		String prepayId = null;
		PaySendData paySendData = new PaySendData();
		// 构建微信支付请求参数集合
		paySendData.setAppId(Constant.APP_ID_APP);
		paySendData.setMch_id(Constant.MCH_ID_APP);
		paySendData.setNotify_url(VO.getNotityUrl());
		paySendData.setTrade_type(Constant.TRADE_TYPE_APP);
		paySendData.setDevice_info(Constant.WEB);
		paySendData.setBody(VO.getBody());
		paySendData.setNonce_str(PayUtils.getRandomStr(32));
		paySendData.setOut_trade_no(VO.getOrderNo());
		paySendData.setTotal_fee(VO.getOrderBalance());
		paySendData.setSpbill_create_ip(Constant.CREATEIP);
		// 将参数拼成map,生产签名
		String sign = PayUtils.getForAppSign(buildParamMap(paySendData));
		paySendData.setSign(sign);
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.PostForAPP(Constant.UNIFIED_ORDER_URL, reqXml, false);
			try {
				resultMap = PayUtils.parseXml(response.getEntity().getContent());
				// 关闭流
				EntityUtils.consume(response.getEntity());
			} finally {
				response.close();
			}
		} catch (Exception e) {
			LOGGER.error("微信支付统一下单异常");
		}
		String return_code = resultMap.get("return_code").toString();
		String result_code = resultMap.get("result_code").toString();
		if (Constant.RETURN_SUCCESS.equals(return_code) && Constant.RETURN_SUCCESS.equals(result_code)) {
			// return_code=通信标识
			// result_code=交易标识
			// 只有当returnCode与resultCode均返回“success”，才代表微信支付统一下单成功
			prepayId = resultMap.get("prepay_id").toString();

			if (!StringUtils.isEmpty(prepayId)) {
				payMap.put("appid", Constant.APP_ID_APP);
				payMap.put("partnerid", Constant.MCH_ID_APP);
				payMap.put("prepayid", prepayId);
				payMap.put("package", "Sign=WXPay");
				String nonceStr = PayUtils.getRandomStr(32);// 不长于32位的随机字符串
				payMap.put("nonceStr", nonceStr);
				String timeStamp = PayUtils.getTimeStamp();// 当前时间戳
				payMap.put("timestamp", timeStamp);

				String paySign = PayUtils.getForAppSign(payMap);
				payMap.put("paySign", paySign.subSequence(0, 31));
//				payMap.put("paySign", paySign);
				return payMap;
			}

		}
		return payMap;
	}

	
	/**
	 * 针对用户购买的洗车订单进行退款流程处理
	 * 
	 * @param VO
	 * @return
	 */
	public boolean refund(WXOrderVO vo) {
		Map<String, Object> resultMap = null;
		PaySendData paySendData = new PaySendData();
		// 构建微信支付请求参数集合
		paySendData.setAppId(Constant.APP_ID);
		paySendData.setMch_id(Constant.MCH_ID);
		paySendData.setNonce_str(PayUtils.getRandomStr(32));
		// Out_trade_no与Transaction_id二选一
		paySendData.setOut_trade_no(vo.getOrderNo());
		paySendData.setOut_refund_no(vo.getOutRefundNo());
		paySendData.setTotal_fee(vo.getOrderBalance());
		paySendData.setRefund_fee(vo.getRefundBalance());
		paySendData.setOp_user_id(Constant.MCH_ID);
		paySendData.setNotify_url(vo.getNotityUrl());
		// 将参数拼成map,生产签名
		paySendData.setSign(PayUtils.getSign(buildParamMap(paySendData)));
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.Post(Constant.REFUND_ORDER_URL, reqXml, true);
			try {
				resultMap = PayUtils.parseXml(response.getEntity().getContent());
				// 关闭流
				EntityUtils.consume(response.getEntity());
			} finally {
				response.close();
			}
		} catch (Exception e) {
			LOGGER.error("微信退款异常");
		}
		String return_code = resultMap.get("return_code").toString();
		String result_code = resultMap.get("result_code").toString();
		if (Constant.RETURN_SUCCESS.equals(return_code) && Constant.RETURN_SUCCESS.equals(result_code)) {
			return true;
		}

		return false;
	}
	
	/**
	 * 针对用户购买的洗车订单进行退款流程处理
	 * 
	 * @param VO
	 * @return
	 */
	public boolean refundForApp(WXOrderVO vo) {
		Map<String, Object> resultMap = null;
		PaySendData paySendData = new PaySendData();
		// 构建微信支付请求参数集合
		paySendData.setAppId(Constant.APP_ID_APP);
		paySendData.setMch_id(Constant.MCH_ID_APP);
		paySendData.setNonce_str(PayUtils.getRandomStr(32));

		// Out_trade_no与Transaction_id二选一
		paySendData.setOut_trade_no(vo.getOrderNo());
		
		paySendData.setOut_refund_no(vo.getOutRefundNo());
		paySendData.setTotal_fee(vo.getOrderBalance());
		paySendData.setRefund_fee(vo.getRefundBalance());
		
		paySendData.setNotify_url(vo.getNotityUrl());
		// 将参数拼成map,生产签名
		paySendData.setSign(PayUtils.getForAppSign(buildParamMap(paySendData)));
		// 将请求参数对象转换成xml
		String reqXml = PayUtils.sendDataToXml(paySendData);
		try {
			// 发送请求
			CloseableHttpResponse response = HttpUtil.PostForAPP(Constant.REFUND_ORDER_URL, reqXml, true);
			try {
				resultMap = PayUtils.parseXml(response.getEntity().getContent());
				// 关闭流
				EntityUtils.consume(response.getEntity());				
				String return_code = resultMap.get("return_code").toString();
				String result_code = resultMap.get("result_code").toString();
				if (Constant.RETURN_SUCCESS.equals(return_code) && Constant.RETURN_SUCCESS.equals(result_code)) {
					return true;
				}
			} finally {
				response.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("微信退款异常");
		}
		

		return false;
	}

	/**
	 * 构建统一下单参数map 用于生成签名
	 * 
	 * @param data
	 * @return SortedMap<String,Object>
	 */
	private SortedMap<String, Object> buildParamMap(PaySendData data) {
		SortedMap<String, Object> paramters = new TreeMap<String, Object>();
		Field[] fields = data.getClass().getDeclaredFields();
		try {
			for (Field field : fields) {
				field.setAccessible(true);
				if (null != field.get(data)) {
					paramters.put(field.getName().toLowerCase(), field.get(data).toString());
				}
			}
		} catch (Exception e) {
			System.out.print("构建签名map错误: ");
			e.printStackTrace();
		}

		return paramters;
	}

}
